// 定义几个 Applicative 函数

// 定义 existy 函数简化 JavaScript 中对象是否存在的判断
function existy(x) {
    // 使用松散运算符 != 可以区分 null, undefined 和 其他所有对象
    return x != null;
}

function truthy(x) {
    return (x !== false) && existy(x);
}

function cat() {
    var head = _.first(arguments);
    if (existy(head)) {
        return head.concat.apply(head, _.rest(arguments));
    }
    return [];
}

console.log(cat([1, 2, 3], [4, 5], [6, 7, 8]));

function construct(head, tail) {
    return cat([head], _.toArray(tail));
}

console.log(construct(42, [1, 2, 3]));

function mapcat(fun, coll) {
    return cat.apply(null, _.map(coll, fun));
}

console.log(mapcat(function(e) {
    return construct(e, [","]);
}, [1, 2, 3]));

function butLast(coll) {
    return _.toArray(coll).slice(0, -1);
}

function interpose(inter, coll) {
    return butLast(mapcat(function(e) {
        return construct(e, [inter]);
    }, coll));
}

console.log(interpose(",", [1, 2, 3]));

// 函数式编程的一个关键方面：用较低级别的函数来逐步定义和使用离散功能